package main

import (
	"aria-go/log"
	"aria-go/util"
	"fmt"
	"os"
	"runtime"
	"strings"
)

const packageVersion = "0.1.0"
const packageName = "aria-go"

// AllInstructions 注册全部指令包括短指令
// TODO：后续优化换掉
var AllInstructions = []string{"daemon", "D", "dir", "d", "out", "o", "log", "l", "split", "s",
	"http_proxy", "http_user", "http_passwd", "http_proxy_user", "http_proxy_passwd",
	"http_auth_scheme", "http_auth_scheme"}

// NoArgumentInstruction 注册无需参数的指令
// TODO：后续优化换掉
var NoArgumentInstruction = []string{"D", "daemon"}

func main() {
	//1、 处理控制台输入参数
	argsMap := parseArgs()
	fmt.Printf("参数集合：%v", argsMap)

	stdoutLog := false
	var logfile string
	var dir string
	var ufilename string
	split := 0
	daemonMode := false

	//2、 处理并获取参数
	for key := range argsMap {
		switch key {
		//TODO:暂时保留 后续支持后台运行
		case "D", "daemon":
			daemonMode = true
		case "d", "dir":
			dir := argsMap[key].(string)
		case "o", "out":
			ufilename := argsMap[key].(string)
		case "s", "split":
			split := argsMap[key].(int64)
			if split < 0 && split > 5 {
				fmt.Println("split 必须在1到5之间")
				showUsage()
			}
			os.Exit(1)
		}

		//3、获取日志路径设置日志输出
		logL, okL := argsMap["logL"]
		logPath, okLongL := argsMap["logPath"]
		if okL || okLongL {
			if logL != nil {
				logfile = logL.(string)
			} else {
				logfile = logPath.(string)
			}
		} else {
			stdoutLog = true
		}

		// 4、 设置日志相关设置
		logger := log.SimpleLogger{}
		if stdoutLog {
			logger.New(os.Stdout)
		} else if len(logfile) > 0 {
			logger.New(logfile)
		} else {
			if runtime.GOOS == "windows" {
				homeDir, err := os.UserHomeDir()
				if err != nil {
					fmt.Println("获取用户目录错误")
					os.Exit(1)
				}
				logger.New(homeDir + "/aria-go.log")
			} else {
				logger.New("/dev/null")
			}
		}

		//5、设置后台运行
		if daemonMode {
			fmt.Println("暂时不支持后台运行")
		}
		//6. 设置下载引擎

	}

}

// 解析参数
func parseArgs() map[string]interface{} {
	argsMap := make(map[string]interface{})
	args := os.Args[1:]
	for i := 0; i < len(args); {
		arg := strings.Replace(args[i], "_", "", 2)
		if util.StringArrayContains(AllInstructions, arg) {
			if util.StringArrayContains(NoArgumentInstruction, arg) {
				argsMap[arg] = true
				i++
			} else {
				if arg == "v" || arg == "version" {
					showVersion()
					os.Exit(1)
				} else if arg == "h" || arg == "help" {
					showUsage()
					os.Exit(1)
				}
				argsMap[arg] = args[i+1]
				i = i + 2
			}
		} else {
			fmt.Println("请输入正确的参数指令，如有疑问请参考下列帮助。")
			fmt.Println()
			fmt.Println()
			showUsage()
		}
	}
	return argsMap
}

// 获取帮助
func showUsage() {
	fmt.Println("Usage: ", packageName, " [options] URL ...")
	fmt.Println("Options:")
	fmt.Println(" -d, --dir=DIR              存放下载文件的目录.")
	fmt.Println(" -o, --out=FILE             下载文件的文件名.")
	fmt.Println(" -l, --log=LOG              存储日志的文件路径。如果指定了“-”，日志写入标准输出")
	//fmt.Println(" -D, --daemon               后台运行.")
	fmt.Println(" -s, --split=N              使用s个连接下载文件。 s 必须介于 1 和 5 之间。如果指定了此选项，则使用第一个 URL，而忽略其他 URL。")
	fmt.Println(" --http-proxy=HOST:PORT     使用 HTTP 代理服务器。这会影响所有 URL.")
	fmt.Println(" --http-user=USER           设置 HTTP 用户。这会影响所有 URL。")
	fmt.Println(" --http-passwd=PASSWD       设置 HTTP 密码。这会影响所有 URL。")
	fmt.Println(" --http-proxy-user=USER     设置 HTTP 代理用户。这会影响所有 URL")
	fmt.Println(" --http-proxy-passwd=PASSWD 设置 HTTP 代理密码。这会影响所有 URL。")
	fmt.Println(" --http-auth-scheme=SCHEME  设置 HTTP 认证方案。目前，BASIC 是唯一支持的方案。")
	fmt.Println(" -v, --version              打印版本号并退出。")
	fmt.Println(" -h, --help                打印此消息并退出。")
	fmt.Println("URL:")
	fmt.Println(" 您可以指定多个 URL。所有 URL 必须指向同一个文件，否则下载失败。")
	fmt.Println("例子：")
	fmt.Println(" 通过 1 个连接下载文件：")
	fmt.Println("  aria-go http://AAA.BBB.CCC/file.zip")
	fmt.Println(" 通过 2 个连接下载文件：")
	fmt.Println("  aria-go -s 2 http://AAA.BBB.CCC/file.zip")
	fmt.Println(" 通过 2 个连接下载一个文件，每个连接到不同的服务器。")
	fmt.Println("  aria-go http://AAA.BBB.CCC/file.zip http://DDD.EEE.FFF/GGG/file.zip")

}

// 显示版本
func showVersion() {
	fmt.Println(packageName, " version ", packageVersion)
}
